package com.silence.springboot.handler;

import com.silence.springboot.common.Result;
import com.silence.springboot.enums.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * @author silence
 * @email 792245022@qq.com
 * @create 2023-08-28 17:06
 */
@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public Result<?> handleException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException：", e);
        // 获取所有异常信息
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        // 错误信息
        String errorMsg = e.getMessage();
        // 判断是否有错误信息
        if (CollectionUtils.isNotEmpty(allErrors)) {
            StringBuilder errorBuilder = new StringBuilder();
            StringJoiner sj = new StringJoiner("，");
            allErrors.forEach(item -> {
                FieldError fieldError = ((FieldError) item);
                errorBuilder.append(fieldError.getField())
                        .append("(")
                        .append(fieldError.getRejectedValue())
                        .append(")")
                        .append("：")
                        .append(fieldError.getDefaultMessage());
                sj.add(errorBuilder);
            });
            // 打印错误日志
            errorMsg = sj.toString();
            // 获取方法信息
            Method method = e.getParameter().getMethod();
            if (Objects.nonNull(method)) {
                log.warn("{}.{} 参数校验不通过：{}", method.getDeclaringClass().getName(), method.getName(), errorMsg);
            } else {
                log.warn("参数校验不通过：" + errorMsg, e);
            }
            return Result.<Void>builder()
                    .code(ResultCode.VALIDATE_ERROR.getCode())
                    .msg(ResultCode.VALIDATE_ERROR.getMsg())
                    .build();
        }
        log.warn("参数校验不通过，绑定结果中异常为空：" + errorMsg, e);
        return Result.<Void>builder()
                .code(ResultCode.FAILED.getCode())
                .msg(errorMsg)
                .build();
    }

    /**
     * Handles exceptions of type Exception.
     *
     * @param e The exception to handle.
     * @return The result of handling the exception.
     */
    @ExceptionHandler(value = {Exception.class})
    public Result<Void> handleException(Exception e) {
        log.error("Exception：", e);
        return Result.<Void>builder()
                .code(ResultCode.FAILED.getCode())
                .msg("系统异常，请联系管理员！")
                .build();
    }

}
